package tomsung.cloud.agdc.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import tomsung.cloud.agdc.bean.BeamStrength;
import tomsung.cloud.agdc.bean.Co2;
import tomsung.cloud.agdc.bean.Device;
import tomsung.cloud.agdc.bean.Humidity;
import tomsung.cloud.agdc.bean.Temperature;
import tomsung.cloud.agdc.common.Const;
import tomsung.cloud.agdc.common.DevType;
import tomsung.cloud.agdc.model.JsonObject;
import tomsung.cloud.agdc.model.JsonRequest;
import tomsung.cloud.agdc.model.JsonResponse;
import tomsung.cloud.agdc.service.BeamStrengthService;
import tomsung.cloud.agdc.service.Co2Service;
import tomsung.cloud.agdc.service.DeviceService;
import tomsung.cloud.agdc.service.HumidityService;
import tomsung.cloud.agdc.service.TemperatureService;
import tomsung.cloud.agdc.util.DateUtil;

@Controller
public class Sensor2PCController extends CommonController {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private BeamStrengthService beamStrengthService;

	@Autowired
	private Co2Service co2Service;
	
	@Autowired
	private TemperatureService tempService;

	@Autowired
	private HumidityService humidityService;

	@Autowired
	private DeviceService deviceService;
	
	@ResponseBody
	@RequestMapping(value = "/sensor2pc", method = RequestMethod.POST)
	protected JsonObject transer(final HttpServletRequest request, @RequestBody JsonRequest req) {
		return super.transer(request, req);
	}
	/**
	 * 获取二氧化碳
	 * 
	 * @return
	 */
	public JsonResponse GET_CO2(JsonRequest req) {
		JsonResponse res = req.getRep();
		try {
			Integer greenhouseId = (Integer) req.V.get(Const.GREENHOUSEID);
			List<Device> devices = getDevice(greenhouseId, DevType.CO2_SENSOR);

			List<Long> systemIds = new ArrayList<Long>();
			for (Device device : devices) {
				systemIds.add(device.getSystemid());
			}

			Date beginTime = DateUtil.getCalendar((String) req.V.get(Const.BEGINDATETIME)).getTime();
			Date endTime = DateUtil.getCalendar((String) req.V.get(Const.ENDDATETIME)).getTime();

			List<Co2> co2s = co2Service.selectCo2BySystemId(systemIds, beginTime, endTime);

			List<ResData> datas = new ArrayList<ResData>();
			for (Co2 beam : co2s) {
				ResData data = new ResData();
				data.DATA = beam.getCo2data();
				data.TIME = beam.getTime();
				datas.add(data);
			}

			ReturnData returnData = processData(beginTime, endTime, datas);
			res.V.put("CO2_DATA", returnData);
		} catch (Exception e) {
			res.R = false;
			logger.error(e.getMessage(), e);
		}
		return res;
	}
	
	/**
	 * 获取光照强度
	 * 
	 * @return
	 */
	public JsonResponse GET_BEAM_STRENGTH(JsonRequest req) {
		JsonResponse res = req.getRep();
		try {
			Integer greenhouseId = (Integer) req.V.get(Const.GREENHOUSEID);
			List<Device> devices = getDevice(greenhouseId, DevType.LIGHT_INTENSITY);

			List<Long> systemIds = new ArrayList<Long>();
			for (Device device : devices) {
				systemIds.add(device.getSystemid());
			}

			Date beginTime = DateUtil.getCalendar((String) req.V.get(Const.BEGINDATETIME)).getTime();
			Date endTime = DateUtil.getCalendar((String) req.V.get(Const.ENDDATETIME)).getTime();

			List<BeamStrength> beams = beamStrengthService.selectBeamStrengthBySystemId(systemIds, beginTime, endTime);

			List<ResData> datas = new ArrayList<ResData>();
			for (BeamStrength beam : beams) {
				ResData data = new ResData();
				data.DATA = beam.getBeamdata();
				data.TIME = beam.getTime();
				datas.add(data);
			}

			ReturnData returnData = processData(beginTime, endTime, datas);
			res.V.put("BEAM_DATA", returnData);
		} catch (Exception e) {
			res.R = false;
			logger.error(e.getMessage(), e);
		}
		return res;
	}

	private ReturnData processData(Date beginTime, Date endTime, List<ResData> datas) {
		ReturnData res = new ReturnData();
		Calendar cal = Calendar.getInstance();
		Map<String, List<BigDecimal>> day2Data = new LinkedHashMap<String, List<BigDecimal>>();
		long between = endTime.getTime() - beginTime.getTime();
		if (between > (24 * 3600000)) {
			for (ResData data : datas) {
				cal.setTime(data.TIME);
				Integer day = cal.get(Calendar.DATE);
				Integer month = cal.get(Calendar.MONTH) + 1;
				Integer year = cal.get(Calendar.YEAR);
				String key = String.valueOf(year) + "," + String.valueOf(month) + "," + String.valueOf(day);
				List<BigDecimal> ds = day2Data.get(key);
				if (ds == null) {
					ds = new ArrayList<BigDecimal>();
					ds.add(data.DATA);
					day2Data.put(key, ds);
				} else {
					ds.add(data.DATA);
				}
			}

			for (Map.Entry<String, List<BigDecimal>> entry : day2Data.entrySet()) {
				String yearMonthDays = entry.getKey();
				String yearMonthDay[] = yearMonthDays.split(",");
				res.TIME.add(yearMonthDay[0] + "年" + yearMonthDay[1] + "月" + yearMonthDay[2] + "日");
				res.MAX.add(Collections.max(entry.getValue()));
				res.MIN.add(Collections.min(entry.getValue()));
				res.AVG.add(getAvg(entry.getValue()));
			}
		} else {
			for (ResData data : datas) {
				cal.setTime(data.TIME);
				String key = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
				List<BigDecimal> ds = day2Data.get(key);
				if (ds == null) {
					ds = new ArrayList<BigDecimal>();
					ds.add(data.DATA);
					day2Data.put(key, ds);

				} else {
					ds.add(data.DATA);
				}
			}
			for (Map.Entry<String, List<BigDecimal>> entry : day2Data.entrySet()) {
				res.TIME.add(cal.get(Calendar.HOUR_OF_DAY) + "点");
				res.MAX.add(Collections.max(entry.getValue()));
				res.MIN.add(Collections.min(entry.getValue()));
				res.AVG.add(getAvg(entry.getValue()));
			}
		}

		return res;
	}

	private BigDecimal getAvg(List<BigDecimal> value) {
		BigDecimal res = new BigDecimal(0);
		for (BigDecimal de : value) {
			res = res.add(de);
		}
		return res.divide(new BigDecimal(value.size()), 2);
	}

	/**
	 * 获取空气温度
	 * 
	 * @return
	 */
	public JsonResponse GET_AIR_TEMP(JsonRequest req) {
		return getTemp(req, DevType.AIR_H_AND_T_SENSOR, "AIR_TEMP_DATA");
	}

	/**
	 * 获取空气湿度
	 * 
	 * @return
	 */
	public JsonResponse GET_AIR_HUMIDITY(JsonRequest req) {
		return getHumidity(req, DevType.AIR_H_AND_T_SENSOR, "AIR_HUMIDITY_DATA");
	}

	/**
	 * 获取土壤温度
	 * 
	 * @return
	 */
	public JsonResponse GET_SOIL_TEMP(JsonRequest req) {
		return getTemp(req, DevType.SOIL_TEMP_SENSOR, "SOIL_TEMP_DATA");
	}

	/**
	 * 获取土壤湿度
	 * 
	 * @return
	 */
	public JsonResponse GET_SOIL_HUMIDITY(JsonRequest req) {
		return getHumidity(req, DevType.SOIL_HUMI_SENSOR, "SOIL_HUMIDITY_DATA");
	}

	private JsonResponse getHumidity(JsonRequest req, int devType, String v) {
		JsonResponse res = req.getRep();
		try {
			Integer greenhouseId = (Integer) req.V.get(Const.GREENHOUSEID);
			List<Device> devices = getDevice(greenhouseId, devType);
			List<Long> systemIds = new ArrayList<Long>();
			for (Device device : devices) {
				systemIds.add(device.getSystemid());
			}

			Date beginTime = DateUtil.getCalendar((String) req.V.get(Const.BEGINDATETIME)).getTime();
			Date endTime = DateUtil.getCalendar((String) req.V.get(Const.ENDDATETIME)).getTime();

			List<Humidity> humiditys = humidityService.getHumidityDataBySystemId(systemIds, beginTime, endTime, devType);
			List<ResData> datas = new ArrayList<ResData>();
			for (Humidity humidity : humiditys) {
				ResData data = new ResData();
				data.DATA = humidity.getHumiditydata();
				data.TIME = humidity.getTime();
				datas.add(data);
			}
			ReturnData returnData = processData(beginTime, endTime, datas);
			res.V.put(v, returnData);
		} catch (Exception e) {
			res.R = false;
			logger.error(e.getMessage(), e);
		}
		return res;
	}

	private JsonResponse getTemp(JsonRequest req, int devType, String v) {
		JsonResponse res = req.getRep();
		try {
			Integer greenhouseId = (Integer) req.V.get(Const.GREENHOUSEID);
			List<Device> devices = getDevice(greenhouseId, devType);
			List<Long> systemIds = new ArrayList<Long>();
			for (Device device : devices) {
				systemIds.add(device.getSystemid());
			}

			Date beginTime = DateUtil.getCalendar((String) req.V.get(Const.BEGINDATETIME)).getTime();
			Date endTime = DateUtil.getCalendar((String) req.V.get(Const.ENDDATETIME)).getTime();
			List<Temperature> temps = tempService.getTempDataBySystemId(systemIds, beginTime, endTime, devType);
			List<ResData> datas = new ArrayList<ResData>();
			for (Temperature temp : temps) {
				ResData data = new ResData();
				data.DATA = temp.getTempdata();
				data.TIME = temp.getTime();
				datas.add(data);
			}
			ReturnData returnData = processData(beginTime, endTime, datas);
			res.V.put(v, returnData);
		} catch (Exception e) {
			res.R = false;
			logger.error(e.getMessage(), e);
		}
		return res;
	}

	protected List<Device> getDevice(Integer greenhouseId, int devType) {
		List<Device> devs = deviceService.selectDevicesByDeviceTypeInGreenhouse(greenhouseId, devType);
		if (devs != null && devs.size() > 0) {
			return devs;
		} else {
			return new ArrayList<Device>();
		}
	}

	class ResData {
		public BigDecimal DATA = null;
		public Date TIME = null;
	}

	class ReturnData {
		public List<String> TIME = new ArrayList<String>();
		public List<BigDecimal> MAX = new ArrayList<BigDecimal>();
		public List<BigDecimal> MIN = new ArrayList<BigDecimal>();
		public List<BigDecimal> AVG = new ArrayList<BigDecimal>();
	}

}
